#include "com.h"
#include "utils.h"
#include "initcom.h"


#define LABEL_CURSOR        BGREEN " -> " END
#define LABEL_ERROR         BRED   "  x " END
#define LABEL_BLANK                "    "

#define DEFAULT_BAUDRATE    (115200)
#define DEFAULT_BITS        "8 N 1"


int baudlist[] = {
    // 1200,
    2400,
    4800,
    9600,
    38400,
    57600,
    115200,
    230400,
    460800,
    921600,
    1500000
};

char *bitslist[] = {
    "8 N 1",
    "8 E 1",
    "8 O 1",
};

// 8 N 1; 8 N 1.5
bool is_input_bitstr(char *buf)
{
}
// uishow("%s%2d)%2s")

void goodbye(int code)
{
    uishow("\n");
    uishow("gcom: Good Bye  ^_^\n\n");
    exit(code);
}

int uicom_init(void)
{
    char   buffer[256];
    com_t *serial = NULL;
    char  *cursor = NULL;

_scan:
    uishow("+---------------------------------------------+\n");
    uishow("| %-22s%-22s%s\n", "Serial", "", "|");
    uishow("|---------------------------------------------|\n");
    int index = -1;
    int count = scan_com();
    for (int i = 0; i < count; i++) {
        serial = get_com(i);
        if (serial->available) {
            if (index < 0) {
                index = i; 
                cursor = LABEL_CURSOR;
            } else {
                cursor = LABEL_BLANK;
            }
        } else {
            cursor = LABEL_ERROR;
        }
        uishow("| %4s%2d)  %-35s%s\n", cursor, i + 1, serial->friendly_name, "|");
    }
    uishow("+---------------------------------------------+\n");
    CLEAN(buffer);
    uishow("gcom> ");
    fgets(buffer, sizeof(buffer), stdin);
    if (is_str_null(buffer)) { // ctrl+c
        goodbye(1);
    } else if (is_str_enter(buffer)) { // use available com
        serial = get_com(index);
        // goto step_baudrate;
    } else if (is_str_number(buffer, &index)) { // use input number.
        index -= 1;
        if (index >= 0 && index < count) {
            serial = get_com(index);
            if (!serial->available)
                goto _scan;
        } else {
            goto _scan;
        }
    } else {
        goto _scan;
    }
    // select done. open com
    if (open_com(serial)) {
        uishow("open com failed!\n");
        exit(1);
    }

_baudrate:
    index = 0;
    uishow("+---------------------------------------------+\n");
    uishow("| %-22s%-22s%s\n", "Serial", serial->name, "|");
    uishow("| %-22s%-22s%s\n", "Baudrate", "", "|");
    uishow("|---------------------------------------------|\n");
    //uishow(BWHITE "%-9s[%s]\n" END, "BAUDRATE", serial->name);
    for (int i = 0; i < ARRAY_SIZE(baudlist); i++) {
        uishow("| %4s%2d)  %-14d%22s\n",
                (baudlist[i] == DEFAULT_BAUDRATE) ? LABEL_CURSOR : LABEL_BLANK,
                i + 1,
                baudlist[i],
                "|"
              );
    }
    uishow("+---------------------------------------------+\n");
    int baudrate = 0;
    CLEAN(buffer);
    uishow("gcom> ");
    fgets(buffer, sizeof(buffer), stdin);
    if (is_str_null(buffer)) { // key: ctrl+c
        goodbye(1);
    } else if (is_str_enter(buffer)) { // key: Enter, use default_baudrate
        baudrate = DEFAULT_BAUDRATE;
    } else if (is_str_number(buffer, &index)) { // key: xxxx, 
        index -= 1;
        if (index >= 0 && index < ARRAY_SIZE(baudlist)) {
            baudrate = baudlist[index];
        } else {
            goto _baudrate;
        }
    } else {
    }

_bits:
    uishow("+---------------------------------------------+\n");
    uishow("| %-22s%-22s%s\n", "Serial", serial->name, "|");
    uishow("| %-22s%-22d%s\n", "Baudrate", baudrate, "|");
    uishow("| %-22s%-22s%s\n", "Bits", "", "|");
    uishow("|---------------------------------------------|\n");

    for (int i = 0; i < ARRAY_SIZE(bitslist); i++) {
        uishow("| %4s%2d)  %-14s%22s\n",
                (strcmp(bitslist[i], DEFAULT_BITS) == 0) ? LABEL_CURSOR : LABEL_BLANK,
                i + 1,
                bitslist[i],
                "|"
              );
    }
    uishow("+---------------------------------------------+\n");
    com_config_t config;
    CLEAN(config);
    config.baudrate = baudrate;
    config_com(serial, &config);
    return 0;
}
